let _debounceTimeout = null,
    _throttleRunning = false
/**
 * 防抖
 * @param {Function} 执行函数
 * @param {Number} delay 延时ms   
 */
const debounce = (fn, delay = 500) => {
    clearTimeout(_debounceTimeout);
    _debounceTimeout = setTimeout(() => {
        fn();
    }, delay);
}
/**
 * 节流
 * @param {Function} 执行函数
 * @param {Number} delay 延时ms  
 */
const throttle = (fn, delay = 500) => {
    if (_throttleRunning) {
        return;
    }
    _throttleRunning = true;
    fn();
    setTimeout(() => {
        _throttleRunning = false;
    }, delay);
}
/*
 * 验证手机号是否合格
 * true--说明合格
 */
const isMobilePhone = phoneStr => {
    let myreg = /^[1][3,4,5,7,8,9][0-9]{9}$/;
    if (!myreg.test(phoneStr)) {
        return false;
    } else {
        return true;
    }
}

const isPhone = phoneStr => {
    var mobilePhoneReg = /^[1][3,4,5,7,8,9][0-9]{9}$/;
    var fixMobReg = /^((0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$/;
    if (mobilePhoneReg.test(phoneStr) || fixMobReg.test(phoneStr)) {
        return true;
    } else {
        return false;
    }
}

/*
 * 验证身份证号是否合格
 * true--说明合格
 */
const isIdCard = idCardStr => {
    let idcardReg =
        /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/;
    if (idcardReg.test(idCardStr)) {
        return true;
    } else {
        return false;
    }
}

/**
 * 验证车牌号是否合格
 * true--说明合格
 */
const isVehicleNumber = vehicleNumber => {
    let xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/;
    let creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/;
    if (vehicleNumber.length == 7) {
        return creg.test(vehicleNumber);
    } else if (vehicleNumber.length == 8) {
        return xreg.test(vehicleNumber);
    } else {
        return false;
    }
}

/*
 * 验证字符串是否为空（也不能为纯空格）
 * true--说明为空， false--说明不为空
 */
const isEmptyString = string => {
    if (
        string == undefined ||
        typeof string == 'undefined' ||
        !string ||
        string == null ||
        string == '' ||
        /^\s+$/gi.test(string)
    ) {
        return true;
    } else {
        return false;
    }
}

/*
 * 生日转为年龄（精确到月份）
 */
const birsdayToAge = birsday => {
    let aDate = new Date();
    let thisYear = aDate.getFullYear();
    let bDate = new Date(birsday);
    let brith = bDate.getFullYear();
    let age = thisYear - brith;
    if (aDate.getMonth() == bDate.getMonth()) {
        if (aDate.getDate() < bDate.getDate()) {
            age = age - 1;
        }
    } else {
        if (aDate.getMonth() < bDate.getMonth()) {
            age = age - 1;
        }
    }
    return age;
}

/*
 * 验证是否为数字
 */
const isNumber = n => {
    return !isNaN(parseFloat(n)) && isFinite(n);
}

/*
 * 是否为数组
 */
const isArray = obj => {
    return Object.prototype.toString.call(obj) === '[object Array]';
}

/*
 * 是否空数组
 */
const isArrayEmpty = val => {
    if (val && val instanceof Array && val.length > 0) {
        return false;
    } else {
        return true;
    }
}

/*
 * 递归深拷贝
 */
const deepCopy = obj => {
    let result = Array.isArray(obj) ? [] : {};
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            if (typeof obj[key] === 'object' && obj[key] !== null) {
                result[key] = deepCopy(obj[key]);
            } else {
                result[key] = obj[key];
            }
        }
    }
    return result;
}

/**
 * 去除参数空数据（用于向后台传递参数的时候）
 * @param {Object} obj [参数对象]
 */
const filterEmptyData = obj => {
    for (let prop in obj) {
        obj[prop] === '' ? delete obj[prop] : obj[prop];
    }
    return obj;
}

/**
 *数字金额转文字  函数
 *
 * @export
 * @param {*} money
 * @returns
 */
const convertCurrency = money => {
    //汉字的数字
    var cnNums = new Array('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖');
    //基本单位
    var cnIntRadice = new Array('', '拾', '佰', '仟');
    //对应整数部分扩展单位
    var cnIntUnits = new Array('', '万', '亿', '兆');
    //对应小数部分单位
    var cnDecUnits = new Array('角', '分', '毫', '厘');
    //整数金额时后面跟的字符
    var cnInteger = '整';
    //整型完以后的单位
    var cnIntLast = '元';
    //最大处理的数字
    var maxNum = 999999999999999.9999;
    //金额整数部分
    var integerNum;
    //金额小数部分
    var decimalNum;
    //输出的中文金额字符串
    var chineseStr = '';
    //分离金额后用的数组，预定义
    var parts;
    if (money == '') {
        return '';
    }
    money = parseFloat(money);
    if (money >= maxNum) {
        //超出最大处理数字
        return '';
    }
    if (money == 0) {
        chineseStr = cnNums[0] + cnIntLast + cnInteger;
        return chineseStr;
    }
    //转换为字符串
    money = money.toString();
    if (money.indexOf('.') == -1) {
        integerNum = money;
        decimalNum = '';
    } else {
        parts = money.split('.');
        integerNum = parts[0];
        decimalNum = parts[1].substr(0, 4);
    }
    //获取整型部分转换
    if (parseInt(integerNum, 10) > 0) {
        var zeroCount = 0;
        var IntLen = integerNum.length;
        for (var i = 0; i < IntLen; i++) {
            var n = integerNum.substr(i, 1);
            var p = IntLen - i - 1;
            var q = p / 4;
            var m = p % 4;
            if (n == '0') {
                zeroCount++;
            } else {
                if (zeroCount > 0) {
                    chineseStr += cnNums[0];
                }
                //归零
                zeroCount = 0;
                chineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
            }
            if (m == 0 && zeroCount < 4) {
                chineseStr += cnIntUnits[q];
            }
        }
        chineseStr += cnIntLast;
    }
    //小数部分
    if (decimalNum != '') {
        var decLen = decimalNum.length;
        for (var i = 0; i < decLen; i++) {
            var n = decimalNum.substr(i, 1);
            if (n != '0') {
                chineseStr += cnNums[Number(n)] + cnDecUnits[i];
            }
        }
    }
    if (chineseStr == '') {
        chineseStr += cnNums[0] + cnIntLast + cnInteger;
    } else if (decimalNum == '') {
        chineseStr += cnInteger;
    }
    return chineseStr;
}
/*
 *时间增加或减少几天
 * date  当前日期 例： 2020-06-10
 * days  增加的天数 例： 30
 * return 增加后的天数
 */
const addDate = (date, days) => {
    var d = new Date(date);
    d.setDate(d.getDate() + days);
    var month = d.getMonth() + 1;
    var day = d.getDate();
    if (month < 10) {
        month = "0" + month;
    }
    if (day < 10) {
        day = "0" + day;
    }
    var val = d.getFullYear() + "-" + month + "-" + day;
    return val;
}
/*
 *传入时间戳，展示正常的时间格式 例： formatDate(new Date(时间戳), 'yyyy-MM-dd')
 * date  当前日期 例： 2020-06-10
 * fmt :'yyyy-MM-dd '
 */
const formatDate = (date, fmt) => {
    if (!date) {
        return '';
    }
    if (typeof(date) == 'string') {
        date = date.replace(/-/g, '/').replace(/T/g, ' ').replace(/.[\d]{3}Z/, ' ');
    }
    date = new Date(date);
    if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
    }
    let o = {
        'M+': date.getMonth() + 1,
        'd+': date.getDate(),
        'h+': date.getHours(),
        'm+': date.getMinutes(),
        's+': date.getSeconds(),
        'S': date.getMilliseconds()
    };
    for (let k in o) {
        if (new RegExp(`(${k})`).test(fmt)) {
            let str = o[k] + '';
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
        }
    }
    return fmt;
};

const padLeftZero = (str) => {
    return ('00' + str).substr(str.length);
}
/**
 *@description 秒转化成时分秒
 * @param {string}
 * @returns {string}
 */
const formatSeconds = value => {
    var secondTime = parseInt(value); // 秒
    var minuteTime = 0; // 分
    var hourTime = 0; // 小时
    if (secondTime > 60) { // 如果秒数大于60，将秒数转换成整数
        // 获取分钟，除以60取整数，得到整数分钟
        minuteTime = parseInt(secondTime / 60);
        // 获取秒数，秒数取佘，得到整数秒数
        secondTime = parseInt(secondTime % 60);
        // 如果分钟大于60，将分钟转换成小时
        if (minuteTime > 60) {
            // 获取小时，获取分钟除以60，得到整数小时
            hourTime = parseInt(minuteTime / 60);
            // 获取小时后取佘的分，获取分钟除以60取佘的分
            minuteTime = parseInt(minuteTime % 60);
        }
    }
    var result = "" + parseInt(secondTime) + "秒";

    if (minuteTime > 0) {
        result = "" + parseInt(minuteTime) + "分" + result;
    }
    if (hourTime > 0) {
        result = "" + parseInt(hourTime) + "小时" + result;
    }
    return result;
}
/**
 * @description 身份证算出出生年月和性别
 * @param [string] 身份证号码
 */

const IdentiyInfo = IDCard => {
    // 获取性别
    let sex = parseInt(IDCard.substr(16, 1)) % 2 == 1 ? '男' : '女';
    let brith = IDCard.substring(6, 10) + "-" + IDCard.substring(10, 12) + "-" + IDCard.substring(12, 14);
    //获取出生年月日
    //IDCard.substring(6,10) + "-" + IDCard.substring(10,12) + "-" + IDCard.substring(12,14);
    var yearBirth = IDCard.substring(6, 10);
    var monthBirth = IDCard.substring(10, 12);
    var dayBirth = IDCard.substring(12, 14);
    //获取当前年月日并计算年龄
    var myDate = new Date();
    var monthNow = myDate.getMonth() + 1;
    var dayNow = myDate.getDay();
    var age = myDate.getFullYear() - yearBirth;
    if (monthNow < monthBirth || (monthNow == monthBirth && dayNow < dayBirth)) {
        age--;
    }
    let obj = {
        sex,
        birth: brith,
        age
    }
    return obj;
}

const toInt = function(obj, def) {
    let result = def;
    try {
        let result = Math.parseInt(obj);
        return result;
    } catch {

    }
    return result;
}

const toFixed = (value, num) => {
    if (!num) {
        //默认2位小数
        num = 2;
    }
    if (!value) {
        value = 0;
        return value.toFixed(num);
    }
    if (typeof(value) == "number") {
        return value.toFixed(num);
    }
    return value;
}

/**
 * @description 将金额保留两位小数
 * @money [string] 金额
 * @number [number] 保留小数位数
 */
const getMoney = (money, number = 2) => {
    if (!money) {
        money = 0;
    }
    let moneyVal = Math.ceil(money * 10000);
    let resultVal = (moneyVal / 10000).toFixed(number || 2);
    return resultVal;
}

/**
 * @description 获取量日期天数差
 * @beginDate [Date] 开始日期
 * @endDate [Date] 结束日期
 */
const getDiffDate = (beginDate, endDate) => {
    let date1 = new Date(Date.parse(beginDate.replace(/-/g, "/")));
    let date2 = new Date(Date.parse(endDate.replace(/-/g, "/")));
    let totalDate = parseInt(Math.abs(date2.getTime() - date1.getTime()) / 1000 / 60 / 60 / 24);
    return totalDate;
}
/**
 * @description 获取量日期相差描述
 * @beginDate [Date] 开始日期
 * @endDate [Date] 结束日期
 */
const getDiffSecond = (beginDate, endDate) => {
    let date1 = new Date(Date.parse(beginDate.replace(/-/g, "/")));
    let date2 = new Date(Date.parse(endDate.replace(/-/g, "/")));
    let totalSecond = parseInt(Math.abs(date2.getTime() - date1.getTime()) / 1000);
    return totalSecond;
}

const isValidObject = (obj) => {
    if (obj == null || obj == undefined || obj == '') {
        return false;
    }
    return Object.getOwnPropertyNames(obj).length > 0;

}

/**
 * 对金钱进行向上舍入（保留小数点后两位）
 * 如：10.231，处理后返回10.24
 * @param {Object} val 金钱原始值
 */
const getMoneyCeil = function(val) {
    let moneyVal = Math.trunc(val * 10000);
    let tempNum = Math.ceil(moneyVal / 100);
    let resultVal = (tempNum / 100).toFixed(2);
    return parseFloat(resultVal);
}

/**
 * 是否json字符串
 */
function isJson(value) {
    if (typeof value == 'string') {
        try {
            var obj = JSON.parse(value);
            if (typeof obj == 'object' && obj) {
                return true;
            } else {
                return false;
            }
        } catch (e) {
            return false;
        }
    }
    return false;
}

/**
 * 验证URL格式
 */
function isUrl(value) {
    return /^((https|http|ftp|rtsp|mms):\/\/)(([0-9a-zA-Z_!~*'().&=+$%-]+: )?[0-9a-zA-Z_!~*'().&=+$%-]+@)?(([0-9]{1,3}.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*'()-]+.)*([0-9a-zA-Z][0-9a-zA-Z-]{0,61})?[0-9a-zA-Z].[a-zA-Z]{2,6})(:[0-9]{1,4})?((\/?)|(\/[0-9a-zA-Z_!~*'().;?:@&=+$,%#-]+)+\/?)$/
        .test(value)
}

/**
 * 获取页面栈
 * @param {Number} preIndex为1时获取上一页
 * @return {Object} 
 */
const prePage = (preIndex = 1) => {
    const pages = getCurrentPages();
    const prePage = pages[pages.length - (preIndex + 1)];

    return prePage.$vm;
}
// 判断类型集合
const checkStr = (str, type) => {
    switch (type) {
        case 'mobile': //手机号码
            return /^1[3|4|5|6|7|8|9][0-9]{9}$/.test(str);
        case 'tel': //座机
            return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(str);
        case 'card': //身份证
            return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(str);
        case 'mobileCode': //6位数字验证码
            return /^[0-9]{6}$/.test(str)
        case 'pwd': //密码以字母开头，长度在6~18之间，只能包含字母、数字和下划线
            return /^([a-zA-Z0-9_]){6,18}$/.test(str)
        case 'payPwd': //支付密码 6位纯数字
            return /^[0-9]{6}$/.test(str)
        case 'postal': //邮政编码
            return /[1-9]\d{5}(?!\d)/.test(str);
        case 'QQ': //QQ号
            return /^[1-9][0-9]{4,9}$/.test(str);
        case 'email': //邮箱
            return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str);
        case 'money': //金额(小数点2位)
            return /^\d*(?:\.\d{0,2})?$/.test(str);
        case 'URL': //网址
            return /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/.test(str)
        case 'IP': //IP
            return /((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))/.test(str);
        case 'date': //日期时间
            return /^(\d{4})\-(\d{2})\-(\d{2}) (\d{2})(?:\:\d{2}|:(\d{2}):(\d{2}))$/.test(str) ||
                /^(\d{4})\-(\d{2})\-(\d{2})$/
                .test(str)
        case 'number': //数字
            return /^[0-9]+$/.test(str);
        case 'english': //英文
            return /^[a-zA-Z]+$/.test(str);
        case 'chinese': //中文
            return /^[\\u4E00-\\u9FA5]+$/.test(str);
        case 'lower': //小写
            return /^[a-z]+$/.test(str);
        case 'upper': //大写
            return /^[A-Z]+$/.test(str);
        case 'HTML': //HTML标记
            return /<("[^"]*"|'[^']*'|[^'">])*>/.test(str);
        default:
            return true;
    }
}
// 压缩图片
const compressImages = (files) => {
    return new Promise((resolve, reject) => {
        let compressImages = [];
        files.forEach((item, i) => {
            compressImages[i] = new Promise((resolve2, reject2) => {
                uni.getImageInfo({
                    src: item,
                    success(image) {
                        if (image.width > 2500) {
                            uni.compressImage({
                                src: item,
                                quality: 10,
                                width: '2500px',
                                height: 'auto',
                                success(res) {
                                    resolve2({
                                        data: res.tempFilePath
                                    });
                                },
                                fail(err) {
                                    console.error('fail:', err)
                                    reject2({
                                        msg: '图片压缩失败'
                                    })
                                }
                            })
                        } else if (image.height > 3000) {
                            uni.compressImage({
                                src: item,
                                quality: 10,
                                width: 'auto',
                                height: '3000px',
                                success(res) {
                                    resolve2({
                                        data: res.tempFilePath
                                    });
                                },
                                fail(err) {
                                    console.error('fail:', err)
                                    reject2({
                                        msg: '图片压缩失败'
                                    })
                                }
                            })
                            console.log('3000,', newFiles)
                        } else {
                            resolve({
                                data: item
                            });
                        }
                    }
                })

            })
        })
        Promise.all(compressImages).then(res => {
            console.error('res:', res)
            let tempFilePaths = res.map(item => item.data);
            resolve({
                data: tempFilePaths
            })
        }).catch(err => {
            reject({
                msg: err.msg
            })
        })
    })
}


const sha1 = (s) => {
	
	var newS = (function encodeUTF8(s) {
	  var i, r = [], c, x;
	  for (i = 0; i < s.length; i++)
	    if ((c = s.charCodeAt(i)) < 0x80) r.push(c);
	    else if (c < 0x800) r.push(0xC0 + (c >> 6 & 0x1F), 0x80 + (c & 0x3F));
	    else {
	      if ((x = c ^ 0xD800) >> 10 == 0) //对四字节UTF-16转换为Unicode
	        c = (x << 10) + (s.charCodeAt(++i) ^ 0xDC00) + 0x10000,
	          r.push(0xF0 + (c >> 18 & 0x7), 0x80 + (c >> 12 & 0x3F));
	      else r.push(0xE0 + (c >> 12 & 0xF));
	      r.push(0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F));
	    };
	  return r;
	})(s)
	
	var data = new Uint8Array(newS)
	var i, j, t;
	var l = ((data.length + 8) >>> 6 << 4) + 16, s = new Uint8Array(l << 2);
	s.set(new Uint8Array(data.buffer)), s = new Uint32Array(s.buffer);
	for (t = new DataView(s.buffer), i = 0; i < l; i++)s[i] = t.getUint32(i << 2);
	s[data.length >> 2] |= 0x80 << (24 - (data.length & 3) * 8);
	s[l - 1] = data.length << 3;
	var w = [], f = [
	  function () { return m[1] & m[2] | ~m[1] & m[3]; },
	  function () { return m[1] ^ m[2] ^ m[3]; },
	  function () { return m[1] & m[2] | m[1] & m[3] | m[2] & m[3]; },
	  function () { return m[1] ^ m[2] ^ m[3]; }
	], rol = function (n, c) { return n << c | n >>> (32 - c); },
	  k = [1518500249, 1859775393, -1894007588, -899497514],
	  m = [1732584193, -271733879, null, null, -1009589776];
	m[2] = ~m[0], m[3] = ~m[1];
	for (i = 0; i < s.length; i += 16) {
	  var o = m.slice(0);
	  for (j = 0; j < 80; j++)
	    w[j] = j < 16 ? s[i + j] : rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1),
	      t = rol(m[0], 5) + f[j / 20 | 0]() + m[4] + w[j] + k[j / 20 | 0] | 0,
	      m[1] = rol(m[1], 30), m.pop(), m.unshift(t);
	  for (j = 0; j < 5; j++)m[j] = m[j] + o[j] | 0;
	};
	t = new DataView(new Uint32Array(m).buffer);
	for (var i = 0; i < 5; i++)m[i] = t.getUint32(i << 2);
		
	var hex = Array.prototype.map.call(new Uint8Array(new Uint32Array(m).buffer), function (e) {
	  return (e < 16 ? "0" : "") + e.toString(16);
	}).join("");
	return hex;
}

const randString = (x) => {
	let s = "";
	while (s.length < x && x > 0) {
		const v = Math.random() < 0.5 ? 32 : 0;
		s += String.fromCharCode(
			Math.round(Math.random() * (122 - v - (97 - v)) + (97 - v))
		);
	}
	return s;
}

export {
    getMoneyCeil,
    isValidObject,
    isPhone,
    isMobilePhone,
    isIdCard,
    isVehicleNumber,
    isEmptyString,
    isNumber,
    isArray,
    isArrayEmpty,
    birsdayToAge,
    IdentiyInfo,
    deepCopy,
    filterEmptyData,
    debounce,
    throttle,
    convertCurrency,
    addDate,
    formatDate,
    formatSeconds,
    getDiffSecond,
    toInt,
    toFixed,
    getMoney,
    getDiffDate,
    isJson,
    isUrl,
    prePage,
    checkStr,
    compressImages,
	sha1,
	randString
};
